package p2p.tracker;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import p2p.tracker.message.Message;
import p2p.tracker.message.MessageHandler;

public class Tracker implements Runnable {

	private int TRACKER_PORT = 4711;
	private int CLIENT_PORT = 3124;

	private boolean isRunning = false;
	private DatagramSocket trackerSocket;
	private DatagramSocket clientSocket;

	private static Tracker instance;
	private TrackerListener listener;
	//private int clientPort;

	private Tracker() throws SocketException {
		// TODO Implement logic in Tracker ctor
	}

	public void listen() {

		try {

			byte[] recieveData = new byte[1024];

			DatagramPacket request = new DatagramPacket(recieveData,
					recieveData.length);

			this.trackerSocket.receive(request);

			this.listener.logEvent("Message recieved from "
					+ request.getAddress().getHostName() + " on port "
					+ request.getPort());
			
			Message p2pRequest = new Message(request, recieveData);
			
			//this.setClientPort(p2pRequest.getClientPort());			
									
			this.listener.logEvent("Message " + p2pRequest.toString());

			new MessageHandler(this, p2pRequest).run();

		} catch (IOException e) {

			e.printStackTrace();

		}

	}

	public void stopTracker() {

		if (this.isRunning) {

			this.listener.logEvent("Server is stopping");

			this.isRunning = false;
			this.trackerSocket.close();
			this.clientSocket.close();
			this.listener.logEvent("Server is down");

		}

	}

	public static Tracker getInstance() {
		try {

			if (instance == null)
				instance = new Tracker();

		} catch (SocketException e) {
			e.printStackTrace();
		}

		return instance;

	}

	public void addListener(TrackerListener listener) {

		this.listener = listener;

	}

	public void sendResponse(byte[] response, InetAddress address, int port)
			throws IOException {

//		DatagramPacket responsePacket = new DatagramPacket(response,
//				response.length, address, CLIENT_PORT);
		
		this.listener.logEvent("SEND RESPONSE METHOD!!!");
		this.listener.logEvent("Response : "  + response + " IP : "  + address + " Port : "  + port);				
		
		DatagramPacket responsePacket = new DatagramPacket(response,
		response.length, address, port);	
				
		this.clientSocket.setSoTimeout(10000);

		this.clientSocket.send(responsePacket);

		this.listener.logEvent("Response sendet to IP: " + address.getHostName() + " on port: " + port);

	}

	@Override
	public void run() {
		try {

			this.trackerSocket = new DatagramSocket(TRACKER_PORT);
			this.clientSocket = new DatagramSocket();

//			this.listener.logEvent("Server is Running on Trackerport "
//					+ TRACKER_PORT + " Clientport " + CLIENT_PORT);
			
			this.listener.logEvent("Server is Running on Trackerport "
					+ TRACKER_PORT);

			this.isRunning = true;

			while (isRunning)
				this.listen();

		} catch (SocketException e) {
			e.printStackTrace();
		}
	}

	public boolean isRunning() {
		return this.isRunning;
	}

	public TrackerListener getListener() {
		return this.listener;
	}

//	public int getClientPort() {
//		return clientPort;
//	}
//
//	public void setClientPort(int clientPort) {
//		this.clientPort = clientPort;
//	}

}
